/**
 * 权限服务实现类 - 处理RBAC权限管理和用户权限验证的核心业务逻辑
 *
 * 开发人员：马勇俐
 * 开发时间：2025-11-16 至 2025-11-20
 * 模块职责：实现用户权限验证、菜单权限获取、角色权限继承等核心业务逻辑，支持完整的RBAC权限模型
 *
 * 技术要点：
 * - 多租户权限管理和角色继承机制
 * - 用户菜单权限动态生成和缓存
 * - 权限代码验证和授权决策机制
 * - 菜单可见性和功能权限控制逻辑
 * - RBAC模型的完整权限验证实现
 *
 * 开发故事：负责权限服务的核心业务逻辑实现，与权限服务接口和前端路由深度配合，为系统提供灵活的权限管理和访问控制服务。
 */
package com.pbl.service.impl;

import com.pbl.dto.UserMenuDto;
import com.pbl.entity.Role;
import com.pbl.entity.RolePermission;
import com.pbl.entity.User;
import com.pbl.entity.UserRole;
import com.pbl.repository.RolePermissionRepository;
import com.pbl.repository.UserRepository;
import com.pbl.repository.UserRoleRepository;
import com.pbl.service.PermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 权限服务实现类 - 提供用户权限验证和菜单权限管理的核心业务逻辑
 */
@Service
public class PermissionServiceImpl implements PermissionService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserRoleRepository userRoleRepository;

    @Autowired
    private RolePermissionRepository rolePermissionRepository;

    @Override
    public UserMenuDto getUserMenuAndPermissions(Long userId) {
        // 查询用户信息
        User user = userRepository.findById(userId).orElse(null);
        if (user == null) {
            return null;
        }

        // 查询用户角色
        List<UserRole> userRoles = userRoleRepository.findByUser_Id(userId);
        List<String> roleCodes = userRoles.stream()
                .map(ur -> ur.getRole().getCode())
                .collect(Collectors.toList());

        // 查询用户权限
        List<RolePermission> rolePermissions = rolePermissionRepository.findByUserId(userId);
        List<String> permissions = rolePermissions.stream()
                .map(RolePermission::getPermissionCode)
                .distinct()
                .collect(Collectors.toList());

        // 构建菜单
        List<UserMenuDto.MenuItem> menus = buildMenus(permissions);

        return UserMenuDto.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .enterpriseId(user.getEnterprise().getId())
                .enterpriseName(user.getEnterprise().getName())
                .roles(roleCodes)
                .permissions(permissions)
                .menus(menus)
                .build();
    }

    @Override
    public boolean hasPermission(Long userId, String permissionCode) {
        return rolePermissionRepository.userHasPermission(userId, permissionCode);
    }

    /**
     * 根据权限构建菜单
     */
    private List<UserMenuDto.MenuItem> buildMenus(List<String> permissions) {
        List<UserMenuDto.MenuItem> menus = new ArrayList<>();
        
        Map<String, MenuConfig> menuConfigs = new HashMap<>();
        menuConfigs.put("dashboard:view", new MenuConfig("数据看板", "/dashboard", "el-icon-data-analysis"));
        menuConfigs.put("payment:view", new MenuConfig("支付管理", "/payments", "el-icon-money"));
        menuConfigs.put("product:view", new MenuConfig("产品管理", "/products", "el-icon-shopping-cart-2"));
        menuConfigs.put("financing:view", new MenuConfig("融资服务", "/financing", "el-icon-bank-card"));
        menuConfigs.put("report:view", new MenuConfig("报表AI", "/reports", "el-icon-chat-dot-round"));
        menuConfigs.put("enterprise:view", new MenuConfig("企业管理", "/enterprises", "el-icon-office-building"));
        menuConfigs.put("user:view", new MenuConfig("用户管理", "/users", "el-icon-user"));

        for (String permission : permissions) {
            MenuConfig config = menuConfigs.get(permission);
            if (config != null) {
                menus.add(UserMenuDto.MenuItem.builder()
                        .name(config.name)
                        .path(config.path)
                        .icon(config.icon)
                        .visible(true)
                        .build());
            }
        }

        return menus;
    }

    private static class MenuConfig {
        String name;
        String path;
        String icon;

        MenuConfig(String name, String path, String icon) {
            this.name = name;
            this.path = path;
            this.icon = icon;
        }
    }
}

